package com.hdax.dm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdax.dm.beans.base.image;
import com.hdax.dm.beans.item.Item;
import com.hdax.dm.beans.item.cinema;
import com.hdax.dm.dto.list.querygoodsinfosDto;
import com.hdax.dm.feign.imagefeign;
import com.hdax.dm.mappers.list.itemSearchMapper;
import com.hdax.dm.service.itemSearchService;
import com.hdax.dm.vo.itemSearchVo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;

@Service
public class itemSearchServiceImpl extends ServiceImpl<itemSearchMapper,Item> implements itemSearchService {

    private static final String startTime=" 00:00:00";
    private static final String endTime=" 23:59:59";

    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private imagefeign imagefeign;
    @Autowired
    private cinemaServiceImpl cinemaService;


    @Override
    public querygoodsinfosDto itemSearch(itemSearchVo vo) throws IOException {

        //最终响应的DTO对象
        querygoodsinfosDto itemSearchDto = new querygoodsinfosDto();

        /*ES搜索请求对象  负责检索请求*/
        SearchRequest request = new SearchRequest("items");
        /*搜索条件构造器：负责进行多条件拼装  构建查询条件时使用*/
        SearchSourceBuilder builder = new SearchSourceBuilder();
        /*语法高亮建造器*/
        //unified:ES自带的语法高亮器prefix+keyword+suffixl
        //<span style="color :red">keyword</span>
        //preTags: <span style="color :red">
        //postTags: </span>
        HighlightBuilder highlightBuilder = new HighlightBuilder();

        /*多条件查询*/
        /*QueryBuilders:建立所有查询构造器的*/
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        /*开始拼接条件*/
        if(StringUtils.hasLength(vo.getKeyword())){

            /*语法高亮*/
            HighlightBuilder.Field highlighfiled1 = new HighlightBuilder.Field("itemname").highlighterType("unified");
            HighlightBuilder.Field highlighfiled2 = new HighlightBuilder.Field("abstractmessage").highlighterType("unified");

            highlightBuilder.fields().add(highlighfiled1);
            highlightBuilder.fields().add(highlighfiled2);

            boolQueryBuilder.must(QueryBuilders.matchQuery("itemname",vo.getKeyword()));/*第一个参数为ES中字段名称，第二个为他的值*/
            /*如果abstactmessage中也存在keyword，则得分更高，排名更靠前*/
            boolQueryBuilder.should(QueryBuilders.matchQuery("abstractmessage",vo.getKeyword()));
        }
        //地区查找
        if(vo.getAreaId()!=0){
            //精确查找：不打分，不排名
            boolQueryBuilder.must(QueryBuilders.termQuery("areaid",vo.getAreaId()));
        }

        //一二级分类
        if(vo.getItemTypeId1()!=0){
            //精确查找：不打分，不排名
            boolQueryBuilder.must(QueryBuilders.termQuery("itemtype1id",vo.getItemTypeId1()));
        }
        if(vo.getItemTypeId2()!=0){
            //精确查找：不打分，不排名
            boolQueryBuilder.must(QueryBuilders.termQuery("itemtype2id",vo.getItemTypeId2()));
        }

        //时间范围查询
        if (StringUtils.hasLength(vo.getStartTime()) && StringUtils.hasLength(vo.getEndTime())){
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("starttime");

            //设置时间起止
            rangeQueryBuilder.gte(vo.getStartTime().concat(startTime));
            rangeQueryBuilder.lte(vo.getEndTime().concat(endTime));

            boolQueryBuilder.must(rangeQueryBuilder);
        }

        //排序查询
        // recentSell recentShow recommend
        String sortField = "isrecommend"; //排序字段

        switch(vo.getSort()){
            case "recentSell":sortField = "createdtime";break;
            case "recentShow":sortField = "starttime";break;
            case "recommend":sortField = "isrecommend";break;
        }
        builder.sort(sortField, SortOrder.DESC);//进行降序排列

        //设置高亮的样式
        //设定语法高亮的字段不会自动添加到es的field中
        //xxx演唱会

        //如果要多个字段高亮需设为false
        highlightBuilder.requireFieldMatch(true);
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        builder.highlighter(highlightBuilder);

        builder.query(boolQueryBuilder);
        //此过程理解为将builder中的属性转化为JSON字符串然后进行ES查询
        request.source(builder);

        //ES响应对象
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        //获取本次查询结果的总条数
        SearchHits searchHits = response.getHits();
        int totalCount = (int) searchHits.getTotalHits().value; //总条数
        itemSearchDto.setCurrentPage(vo.getCurrentPage());//当前页码
        itemSearchDto.setPageSize(vo.getPageSize()); //每页条数
        itemSearchDto.setRows(new ArrayList<querygoodsinfosDto.itemRowDto>());
        itemSearchDto.setPageCount((totalCount % vo.getPageSize() == 0 ?totalCount/vo.getPageSize() : totalCount/vo.getPageSize()+1));
        SearchHit[] hits = response.getHits().getHits();

        //分页处理
        builder.from((vo.getCurrentPage()-1)*vo.getPageSize());
        builder.size(vo.getPageSize());

        for (int i = 0; i < hits.length; i++) {
            //每一行搜索到的商品数据
            querygoodsinfosDto.itemRowDto rowsDto = JSON.parseObject(hits[i].getSourceAsString(), querygoodsinfosDto.itemRowDto.class);
            //远程调用
            image img = imagefeign.image(rowsDto.getId(),2L,1L);
            String imgUrl =img == null ? "":img.getImgUrl();
            rowsDto.setImgUrl(imgUrl);


            if(StringUtils.hasLength(vo.getKeyword())) {
                //关键词设定
                rowsDto.setItemName(StringUtils.arrayToDelimitedString(hits[i].getHighlightFields().get("itemname").getFragments(), ""));

                if (hits[i].getHighlightFields().get("abstractmessage")!=null){
                    rowsDto.setAbstractMessage(StringUtils.arrayToDelimitedString(hits[i].getHighlightFields().get("abstractmessage").getFragments(), ""));
                }

            }
            //把每一行数据都添加到最终的DTO中
            itemSearchDto.getRows().add(rowsDto);
            String cinemaid = JSONObject.parseObject(hits[i].getSourceAsString()).getString("cinemaid");
            cinema cinema= cinemaService.selectOne(Integer.parseInt(cinemaid));
            rowsDto.setAdress(cinema.getAddress());
            rowsDto.setAreaName(cinema.getAreaName());

        }
        
        return itemSearchDto;
    }
}
